package service

import (
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/yourusername/rss-reader-ai/internal/model"
	"github.com/yourusername/rss-reader-ai/internal/repository"
)

// =====================================================
// ArticleService 接口定义
// =====================================================

// ArticleService 文章业务逻辑接口
type ArticleService interface {
	// GetArticle 获取文章详情
	GetArticle(id int64) (*model.Article, error)

	// ListArticles 获取文章列表 (支持复杂筛选)
	ListArticles(filter *ArticleFilter, page, pageSize int) ([]*model.Article, int64, error)

	// SearchArticles 全文搜索文章
	SearchArticles(keyword string, page, pageSize int) ([]*model.Article, int64, error)

	// MarkAsRead 标记文章为已读
	MarkAsRead(id int64) error

	// MarkAsUnread 标记文章为未读
	MarkAsUnread(id int64) error

	// BatchMarkAsRead 批量标记已读
	BatchMarkAsRead(ids []int64) error

	// ToggleFavorite 切换收藏状态
	ToggleFavorite(id int64) error

	// UpdateNote 更新文章笔记
	UpdateNote(id int64, note string) error

	// DeleteArticle 删除文章
	DeleteArticle(id int64) error

	// BatchDeleteArticles 批量删除文章
	BatchDeleteArticles(ids []int64) error

	// GetArticlesByFeed 获取订阅源的文章列表
	GetArticlesByFeed(feedID int64, page, pageSize int) ([]*model.Article, int64, error)

	// GetArticlesByTag 获取标签的文章列表
	GetArticlesByTag(tagName string, page, pageSize int) ([]*model.Article, int64, error)

	// GetUnreadCount 获取未读文章数
	GetUnreadCount() (int64, error)

	// GetFavoriteCount 获取收藏文章数
	GetFavoriteCount() (int64, error)

	// ExportToMarkdown 导出文章为Markdown格式
	ExportToMarkdown(ids []int64) (string, error)
}

// ArticleFilter 文章筛选条件
type ArticleFilter struct {
	FeedID     *int64  // 订阅源ID
	TagName    *string // 标签名
	IsRead     *bool   // 是否已读
	IsFavorite *bool   // 是否收藏
	StartDate  *time.Time
	EndDate    *time.Time
}

// =====================================================
// ArticleService 接口实现
// =====================================================

// articleService 文章业务逻辑实现
type articleService struct {
	articleRepo repository.ArticleRepository
	tagRepo     repository.TagRepository
	feedRepo    repository.FeedRepository
}

// NewArticleService 创建文章业务逻辑实例
func NewArticleService(
	articleRepo repository.ArticleRepository,
	tagRepo repository.TagRepository,
	feedRepo repository.FeedRepository,
) ArticleService {
	return &articleService{
		articleRepo: articleRepo,
		tagRepo:     tagRepo,
		feedRepo:    feedRepo,
	}
}

// GetArticle 获取文章详情
func (s *articleService) GetArticle(id int64) (*model.Article, error) {
	article, err := s.articleRepo.GetByID(id)
	if err != nil {
		return nil, fmt.Errorf("获取文章失败: %w", err)
	}
	return article, nil
}

// ListArticles 获取文章列表 (支持复杂筛选)
func (s *articleService) ListArticles(filter *ArticleFilter, page, pageSize int) ([]*model.Article, int64, error) {
	// 转换为Repository层的Filter
	repoFilter := &repository.ArticleListFilter{
		FeedID:    filter.FeedID,
		IsRead:    filter.IsRead,
		IsStarred: filter.IsFavorite, // Repository使用IsStarred而不是IsFavorite
		StartDate: filter.StartDate,
		EndDate:   filter.EndDate,
		Limit:     pageSize,
		Offset:    (page - 1) * pageSize,
	}

	// 查询文章列表
	articles, err := s.articleRepo.List(repoFilter)
	if err != nil {
		return nil, 0, fmt.Errorf("获取文章列表失败: %w", err)
	}

	// 获取总数
	total, err := s.articleRepo.Count(repoFilter)
	if err != nil {
		return nil, 0, fmt.Errorf("统计文章数量失败: %w", err)
	}

	return articles, total, nil
}

// SearchArticles 全文搜索文章
func (s *articleService) SearchArticles(keyword string, page, pageSize int) ([]*model.Article, int64, error) {
	// 验证关键词
	keyword = strings.TrimSpace(keyword)
	if keyword == "" {
		return nil, 0, fmt.Errorf("搜索关键词不能为空")
	}

	// 使用MySQL FULLTEXT索引搜索
	articles, err := s.articleRepo.Search(keyword, page, pageSize)
	if err != nil {
		return nil, 0, fmt.Errorf("搜索文章失败: %w", err)
	}

	// 统计搜索结果数
	total := int64(len(articles))
	if page == 1 && len(articles) == pageSize {
		// 如果第一页就满了,说明可能有更多结果
		// 实际项目中可以优化为单独的Count查询
		total = int64(pageSize * 10) // 估算值
	}

	return articles, total, nil
}

// MarkAsRead 标记文章为已读
func (s *articleService) MarkAsRead(id int64) error {
	// 检查文章是否存在
	article, err := s.articleRepo.GetByID(id)
	if err != nil {
		return fmt.Errorf("文章不存在: %w", err)
	}

	// 如果已经是已读状态,直接返回
	if article.IsRead {
		return nil
	}

	// 更新为已读
	if err := s.articleRepo.MarkRead(id); err != nil {
		return fmt.Errorf("标记已读失败: %w", err)
	}

	log.Printf("✅ 标记已读: %s", article.Title)
	return nil
}

// MarkAsUnread 标记文章为未读
func (s *articleService) MarkAsUnread(id int64) error {
	// 检查文章是否存在
	article, err := s.articleRepo.GetByID(id)
	if err != nil {
		return fmt.Errorf("文章不存在: %w", err)
	}

	// 如果已经是未读状态,直接返回
	if !article.IsRead {
		return nil
	}

	// 更新为未读
	if err := s.articleRepo.MarkUnread(id); err != nil {
		return fmt.Errorf("标记未读失败: %w", err)
	}

	log.Printf("✅ 标记未读: %s", article.Title)
	return nil
}

// BatchMarkAsRead 批量标记已读
func (s *articleService) BatchMarkAsRead(ids []int64) error {
	if len(ids) == 0 {
		return nil
	}

	// 逐个标记已读
	for _, id := range ids {
		if err := s.articleRepo.MarkRead(id); err != nil {
			log.Printf("⚠️  标记已读失败: ID=%d, Error=%v", id, err)
		}
	}

	log.Printf("✅ 批量标记已读: %d篇文章", len(ids))
	return nil
}

// ToggleFavorite 切换收藏状态
func (s *articleService) ToggleFavorite(id int64) error {
	// 获取当前状态
	article, err := s.articleRepo.GetByID(id)
	if err != nil {
		return fmt.Errorf("文章不存在: %w", err)
	}

	// 使用Repository的ToggleStar方法
	if err := s.articleRepo.ToggleStar(id); err != nil {
		return fmt.Errorf("切换收藏失败: %w", err)
	}

	status := "取消收藏"
	if !article.IsStarred {
		status = "收藏"
	}
	log.Printf("✅ %s: %s", status, article.Title)
	return nil
}

// UpdateNote 更新文章笔记
func (s *articleService) UpdateNote(id int64, note string) error {
	// 检查文章是否存在
	if _, err := s.articleRepo.GetByID(id); err != nil {
		return fmt.Errorf("文章不存在: %w", err)
	}

	// 更新笔记
	if err := s.articleRepo.UpdateFields(id, map[string]interface{}{
		"note": note,
	}); err != nil {
		return fmt.Errorf("更新笔记失败: %w", err)
	}

	log.Printf("✅ 更新笔记成功")
	return nil
}

// DeleteArticle 删除文章
func (s *articleService) DeleteArticle(id int64) error {
	// 检查文章是否存在
	article, err := s.articleRepo.GetByID(id)
	if err != nil {
		return fmt.Errorf("文章不存在: %w", err)
	}

	// 删除文章
	if err := s.articleRepo.Delete(id); err != nil {
		return fmt.Errorf("删除文章失败: %w", err)
	}

	log.Printf("✅ 删除文章: %s", article.Title)
	return nil
}

// BatchDeleteArticles 批量删除文章
func (s *articleService) BatchDeleteArticles(ids []int64) error {
	if len(ids) == 0 {
		return nil
	}

	// 逐个删除
	for _, id := range ids {
		if err := s.articleRepo.Delete(id); err != nil {
			log.Printf("⚠️  删除文章失败: ID=%d, Error=%v", id, err)
		}
	}

	log.Printf("✅ 批量删除: %d篇文章", len(ids))
	return nil
}

// GetArticlesByFeed 获取订阅源的文章列表
func (s *articleService) GetArticlesByFeed(feedID int64, page, pageSize int) ([]*model.Article, int64, error) {
	// 检查订阅源是否存在
	if _, err := s.feedRepo.GetByID(feedID); err != nil {
		return nil, 0, fmt.Errorf("订阅源不存在: %w", err)
	}

	// 查询文章
	filter := &repository.ArticleListFilter{
		FeedID: &feedID,
		Limit:  pageSize,
		Offset: (page - 1) * pageSize,
	}

	articles, err := s.articleRepo.List(filter)
	if err != nil {
		return nil, 0, fmt.Errorf("获取文章列表失败: %w", err)
	}

	total, err := s.articleRepo.Count(filter)
	if err != nil {
		return nil, 0, fmt.Errorf("统计文章数量失败: %w", err)
	}

	return articles, total, nil
}

// GetArticlesByTag 获取标签的文章列表
func (s *articleService) GetArticlesByTag(tagName string, page, pageSize int) ([]*model.Article, int64, error) {
	// 检查标签是否存在
	tag, err := s.tagRepo.GetByName(tagName)
	if err != nil {
		return nil, 0, fmt.Errorf("标签不存在: %w", err)
	}

	// 查询文章(通过Tags数组筛选)
	filter := &repository.ArticleListFilter{
		Tags:   []string{tagName},
		Limit:  pageSize,
		Offset: (page - 1) * pageSize,
	}

	articles, err := s.articleRepo.List(filter)
	if err != nil {
		return nil, 0, fmt.Errorf("获取文章列表失败: %w", err)
	}

	total := int64(tag.ArticleCount)

	return articles, total, nil
}

// GetUnreadCount 获取未读文章数
func (s *articleService) GetUnreadCount() (int64, error) {
	isRead := false
	filter := &repository.ArticleListFilter{
		IsRead: &isRead,
	}

	count, err := s.articleRepo.Count(filter)
	if err != nil {
		return 0, fmt.Errorf("统计未读文章失败: %w", err)
	}

	return count, nil
}

// GetFavoriteCount 获取收藏文章数
func (s *articleService) GetFavoriteCount() (int64, error) {
	isStarred := true
	filter := &repository.ArticleListFilter{
		IsStarred: &isStarred,
	}

	count, err := s.articleRepo.Count(filter)
	if err != nil {
		return 0, fmt.Errorf("统计收藏文章失败: %w", err)
	}

	return count, nil
}

// ExportToMarkdown 导出文章为Markdown格式
func (s *articleService) ExportToMarkdown(ids []int64) (string, error) {
	if len(ids) == 0 {
		return "", fmt.Errorf("请选择要导出的文章")
	}

	// 获取所有文章
	var articles []*model.Article
	for _, id := range ids {
		article, err := s.articleRepo.GetByID(id)
		if err != nil {
			log.Printf("⚠️  跳过不存在的文章: ID=%d", id)
			continue
		}
		articles = append(articles, article)
	}

	if len(articles) == 0 {
		return "", fmt.Errorf("没有可导出的文章")
	}

	// 生成Markdown
	var md strings.Builder
	md.WriteString("# RSS 文章导出\n\n")
	md.WriteString(fmt.Sprintf("导出时间: %s\n\n", time.Now().Format("2006-01-02 15:04:05")))
	md.WriteString(fmt.Sprintf("文章数量: %d\n\n", len(articles)))
	md.WriteString("---\n\n")

	for i, article := range articles {
		md.WriteString(fmt.Sprintf("## %d. %s\n\n", i+1, article.Title))
		
		// 获取订阅源标题
		feedTitle := "未知来源"
		if article.Feed != nil {
			feedTitle = article.Feed.Title
		}
		md.WriteString(fmt.Sprintf("**来源**: %s\n\n", feedTitle))
		
		// 发布时间
		if article.PublishedAt != nil {
			md.WriteString(fmt.Sprintf("**发布时间**: %s\n\n", article.PublishedAt.Format("2006-01-02 15:04:05")))
		}
		md.WriteString(fmt.Sprintf("**链接**: [查看原文](%s)\n\n", article.Link))

		// AI摘要
		if article.HasAISummary() {
			md.WriteString("### 📝 AI摘要\n\n")
			md.WriteString(article.AISummary + "\n\n")
		}

		// 原文描述
		if article.Description != "" {
			md.WriteString("### 📄 文章摘要\n\n")
			md.WriteString(article.Description + "\n\n")
		}

		// 标签
		if len(article.AITags) > 0 {
			md.WriteString("**标签**: ")
			for j, tag := range article.AITags {
				if j > 0 {
					md.WriteString(", ")
				}
				md.WriteString("`" + tag + "`")
			}
			md.WriteString("\n\n")
		}

		// 用户笔记
		if article.UserNote != "" {
			md.WriteString("### 💡 笔记\n\n")
			md.WriteString(article.UserNote + "\n\n")
		}

		md.WriteString("---\n\n")
	}

	log.Printf("✅ 导出成功: %d篇文章", len(articles))
	return md.String(), nil
}
